package cn.zhxu.toys.oss;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

public abstract class AbstractOssManager implements OssManager {

	protected String endpoint;

	protected Long maxSize = (long) (300000 * 1024);

	@Override
	public String upload(String key, File file) {
		String extension = getFileExtension(file.getName());
		String contentType = getContentType(extension);
		try {
			return upload(null, key, contentType, extension, new FileInputStream(file));
		} catch (FileNotFoundException e) {
			throw new RuntimeException("上传出错：", e);
		}
	}

	@Override
	public String upload(String key, String contentType, InputStream inputStream) {
		return upload(null, key, contentType, toExtension(contentType), inputStream);
	}

	@Override
	public String upload(String fileName, String key, String contentType, InputStream inputStream) {
		String extension = null;
		if (fileName != null) {
			int dotIndex = fileName.lastIndexOf('.');
			if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
				extension = fileName.substring(dotIndex);
				fileName = fileName.substring(0, dotIndex);
			}
		}
		if (extension != null && contentType == null) {
			contentType = getContentType(extension);
		}
		if (contentType != null && extension == null) {
			extension = toExtension(contentType);
		}
		return upload(fileName, key, contentType, extension, inputStream);
	}

	public abstract String upload(String fileName, String key, String contentType, String extension, InputStream inputStream);

	protected String resolveFileAccessUrl(String fileKey) {
		return getBaseUrl() + fileKey;
	}

	protected String resolveFileKey(String fileAccessUrl) {
		if (fileAccessUrl != null) {
			String accessUri = uri(fileAccessUrl);
			String baseUri = uri(getBaseUrl());
			if (accessUri.startsWith(baseUri)) {
				return accessUri.substring(baseUri.length());
			}
		}
		return null;
	}

	private String uri(String url) {
		int idx = url.indexOf("://");
		if (idx > 0 && url.length() > idx + 3) {
			return url.substring(idx + 3);
		}
		return url;
	}

	protected String getBaseUrl() {
		String protocol = "https://";
		String host = endpoint;
		if (endpoint.startsWith("http://")) {
			host = host.substring(7);
			protocol = "http://";
		} else if (endpoint.startsWith("https://")) {
			host = host.substring(8);
		}
		if (host.endsWith("/")) {
			host = host.substring(0, host.length() - 1);
		}
		return getBaseAccessUrl(protocol, host);
	}

	protected abstract String getBaseAccessUrl(String protocol, String host);

	protected String getContentType(String fileExtension) {
		if (fileExtension != null && fileExtension.length() > 1) {
			switch (fileExtension.toLowerCase().substring(1)) {
				// 文本
				case "txt":
					return "text/plain";
				case "json":
					return "application/json";
				case "xml":
					return "text/xml";
				case "js":
					return "text/javascript";
				case "html":
					return "text/html";
				// 图片
				case "bmp":
					return "image/bmp";
				case "gif":
					return "image/gif";
				case "jpeg":
					return "image/jpeg";
				case "jpg":
					return "image/jpg";
				case "png":
					return "image/png";
				// 音频
				case "mp3":
					return "video/mp3";
				case "wav":
					return "video/wav";
				// 视频
				case "avi":
					return "video/avi";
				case "mpg":
					return "video/mpg";
				case "mpeg":
					return "video/mpeg";
				case "mp4":
					return "video/mp4";
				// Office
				case "pdf":
					return "application/pdf";
				case "ppt":
					return "application/vnd.ms-powerpoint";
				case "pptx":
					return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
				case "doc":
					return "application/msword";
				case "docx":
					return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
				case "xls":
					return "application/vnd.ms-excel";
				case "xlsx":
					return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
				case "vsd":
					return "application/vnd.visio";
			}
		}
		return null;
	}

	protected String toExtension(String contentType) {
		return ".*";
	}

	protected String getFileExtension(String fileName) {
		return fileName.substring(fileName.lastIndexOf("."));
	}

	public String getEndpoint() {
		return endpoint;
	}

	public void setEndpoint(String endpoint) {
		this.endpoint = endpoint;
	}

	public Long getMaxSize() {
		return maxSize;
	}

	public void setMaxSize(Long maxSize) {
		this.maxSize = maxSize;
	}

}
